import axios from 'axios'
import { Dialog } from 'vant'
import { showLoading, closeLoading } from './loadingHelper'
import { applyCancel, removeFromReqsMap } from './cancelHelper'

const CancelToken = axios.CancelToken

// 需要引进BASE_URL 默认api
const BASE_URL = (window.g && window.g.BASE_URL) || '/api'
const instance = axios.create({})

instance.interceptors.request.use(
  _config => {
    // 添加上ng代理
    _config.url = BASE_URL + _config.url.replace(/[ ]*=[ ]*/g, '=')
    return _config
  },
  error => {
    Promise.reject(error)
  }
)
instance.interceptors.response.use(
  _response => {
    const { status, data: responseData, statusText } = _response
    if (status === 200) {
      const { code, msg, data } = responseData
      if (code === 200) {
        // 返回数据
        return data
      } else if (code === 500) {
        Dialog({ title: '提示', message: '系统维护中，请稍后再试' })
      } else if (code === 401) {
        Dialog({ title: '提示', message: '身份无法识别' })
      } else if (code === 402) {
        Dialog({ title: '提示', message: '客户段地址不正确，请重新登录' })
      } else if (code === 403) {
        Dialog({ title: '提示', message: '非常抱歉，您没有权限使用该功能' })
      } else if (code === 404) {
        Dialog({ title: '提示', message: '没有找到资源' })
      } else {
        Dialog({ title: '提示', message: `请求失败，code: ${code}` })
        Promise.reject({ msg, code })
      }
    } else {
      Dialog({ title: '提示', type: 'error', message: '服务异常' })
      Promise.reject({ msg: `${statusText}`, code: status })
    }
  },
  error => {
    if (error.code === 'ERR_CANCELED') {
      Dialog({ title: '提示', message: '请勿重复提交' })
    } else {
      Dialog({ title: '提示', message: error })
    }
    return Promise.reject(error)
  }
)
const $axios = {
  instance: instance,
  get: async (url, params = {}, config = {}, options = {}) => {
    const loading = options.loading !== false
    loading && showLoading()
    const r = await instance
      .get(
        url,
        Object.assign({ emulateJSON: true, baseURL: instance.defaults.baseURL }, config, {
          params: params,
        })
      )
      .catch(e => {
        closeLoading()
        throw e
      })
    closeLoading()
    return r
  },
  post: async (url, data = {}, config = {}, options = {}) => {
    const loading = options.loading !== false // 是否开启loading
    const repeatCancel = options.repeatCancel !== false // 是否开启重复请求拦截
    loading && showLoading()
    // 处理重复请求
    if (repeatCancel) {
      const source = CancelToken.source() // 生成令牌对象
      config = Object.assign(config, { cancelToken: source.token })
      applyCancel(url, data, source)
    }
    const r = await instance
      .post(url, data, Object.assign({ emulateJSON: true }, config))
      .catch(e => {
        closeLoading()
        // 不是通过 source.cancel() 取消的请求
        if (e.code !== 'ERR_CANCELED') {
          removeFromReqsMap(url, data)
        }
        throw e
      })
    closeLoading()
    removeFromReqsMap(url, data)
    return r
  },
  put: async (url, data, config = {}, options = {}) => {
    const loading = options.loading !== false
    loading && showLoading()
    const r = await instance
      .put(
        url,
        data,
        Object.assign(
          {
            emulateJSON: true,
          },
          config
        )
      )
      .catch(e => {
        closeLoading()
        throw e
      })
    closeLoading()
    return r
  },
  delete: async (url, params, config = {}, options = {}) => {
    const loading = options.loading !== false
    loading && showLoading()
    const r = await instance
      .delete(
        url,
        Object.assign(
          {
            emulateJSON: true,
          },
          config,
          { params: params }
        )
      )
      .catch(e => {
        closeLoading()
        throw e
      })
    closeLoading()
    return r
  },
}

export { $axios }
